<template>
  <div class="title">贪吃蛇</div>
  <div class="gameBox" ref="gameBoxRef" v-if="issnack">
    <ul>
      <li
        v-for="(item, index) in gameMap"
        :key="index"
        :class="{
          tou: item.istou,
          shou: item.isshou,
          jiao: item.isjiao,
          shen: item.isshen,
        }"
      ></li>
    </ul>
  </div>
</template>

<script setup lang="ts">
import { nextTick, ref } from "vue";
// 生成地图
let gameMap: any = [];
// 生成蛇身,记录了地图上的下标
const snackArr = [0, 1, 2, 3, 4];
// 刷新
const issnack = ref(true);

// 生成网格
const initgameMap = () => {
  for (let i = 0; i < 600; i++) {
    gameMap.push({});
  }
};
initgameMap();

// 生成蛇
const createSnack = () => {
  // 蛇头
  gameMap[snackArr[snackArr.length - 1]].istou = true;
  // 蛇首
  gameMap[snackArr[snackArr.length - 2]].isshou = true;
  // 除了第一个和最后两个，其他的都是蛇身
  for (let i = 1; i < snackArr.length - 2; i++) {
    gameMap[snackArr[i]].isshen = true;
  }
  // 蛇脚
  gameMap[snackArr[0]].isjiao = true;
};
createSnack();
// 控制方向
let direction = "down";
document.addEventListener("keydown", (e) => {
  switch (e.keyCode) {
    case 65: // 左
      if (direction !== "right") {
        direction = "left";
      }
      break;
    case 87: // 上
      if (direction !== "down") {
        direction = "up";
      }
      break;
    case 68: // 右
      if (direction !== "left") {
        direction = "right";
      }
      break;
    case 83: // 下
      if (direction !== "up") {
        direction = "down";
      }
      break;
  }
});
// 移动方向
let steps = 0;
switch (direction) {
  case "right":
    steps = 1;
    break;
  case "left":
    steps = -1;
    break;
  case "up":
    steps = -40;
    break;
  case "down":
    steps = 40;
    break;
  default:
}

// 移动函数
const move = () => {
  let touindex = snackArr[snackArr.length - 1];
  let boundaryArr = [
    direction == "right" && (touindex + 1) % 40 == 0,
    direction == "left" && touindex % 40 < 0,
    direction == "down" && touindex >= 600,
    direction == "up" && touindex < 0,
  ];
  if (boundaryArr.includes(true)) {
    alert("游戏结束");
    clearInterval(timer);
    // return;
  } else {
    gameMap.forEach((item) => {
      item.istou = false;
      item.isshou = false;
      item.isjiao = false;
      item.isshen = false;
    });
    // 1.snackArr数组，删除一个元素，加一个元素进去
    snackArr.splice(0, 1);
    // @ts-ignore
    snackArr.push(snackArr[snackArr.length - 1] + steps);

    // 2.重新生成蛇
    createSnack();
    // 3.界面更新
    showSnack();
    async function showSnack() {
      issnack.value = false;
      await nextTick(function () {
        // 加载
        issnack.value = true;
      });
    }
  }
  // if (direction == "right" && (snackArr[snackArr.length - 1] + 1) % 40 == 0) {
  //   alert("游戏结束");
  //   clearInterval(timer);
  //   return;
  // } else if (direction == "left" && snackArr[snackArr.length - 1] % 40 < 0) {
  //   alert("游戏结束");
  //   clearInterval(timer);
  // } else if (direction == "down" && snackArr[snackArr.length - 1] >= 600) {
  //   alert("游戏结束");
  //   clearInterval(timer);
  // } else if (direction == "up" && snackArr[snackArr.length - 1] < 0) {
  //   alert("游戏结束");
  //   clearInterval(timer);
  // }
};
// 蛇的移动
const timer = setInterval(move, 100);
</script>

<style lang="less" scoped>
.title {
  color: aqua;
  text-align: center;
  font-size: 40px;
}
.gameBox {
  width: 1200px;
  height: 450px;
  margin: 0 auto;
  background-color: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(0, 0, 0, 0.3);
  ul {
    // 网格布局
    display: grid;
    // 设置列数 40列 每格30px 15行 30px
    grid-template-columns: repeat(40, 30px);
    grid-template-rows: repeat(15, 30px);
    li {
      height: 30px;
      width: 30px;
      box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
    }
  }
}
.tou::before,
.shou::before,
.shen::before,
.jiao::before {
  content: "";
  width: 30px;
  height: 30px;
  display: block;
}
.tou::before {
  background-color: rgba(0, 0, 0, 0.7);
  border-radius: 50%;
}
.shou::before {
  background-color: rgba(0, 0, 0, 0.5);
}
.jiao::before {
  background-color: rgba(255, 0, 0, 0.7);
}
.shen::before {
  background-color: rgba(0, 0, 0, 0.3);
}
</style>
